{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.8095783502856286\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.258296\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.688430\n",
      "         Iterations 4\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.658669\n",
      "         Iterations 5\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.687305\n",
      "         Iterations 5\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.689192\n",
      "         Iterations 4\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.621313\n",
      "         Iterations 5\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.677248\n",
      "         Iterations 5\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.672177\n",
      "         Iterations 4\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:696: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully.\n",
      "         Current function value: 0.261689\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.260816\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.260514\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.260098\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259965\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259452\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259076\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259358\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259295\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259160\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259157\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259144\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259142\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259002\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.258794\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259154\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.258985\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.258863\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259144\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259157\n",
      "         Iterations 7\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.333308\n",
      "         Iterations 7\n",
      "The p-value of M1FreqL6M_Bin_WOE is 0.0 \n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.400585\n",
      "         Iterations 6\n",
      "The p-value of maxUrateL3M_Bin_WOE is 6.337094489696354e-52 \n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.402467\n",
      "         Iterations 6\n",
      "The p-value of maxUrateL6M_Bin_WOE is 1.794768730395449e-30 \n",
      "Optimization terminated successfully.    (Exit mode 0)\n",
      "            Current function value: 0.280759550874888\n",
      "            Iterations: 94\n",
      "            Function evaluations: 94\n",
      "            Gradient evaluations: 94\n",
      "Optimization terminated successfully.    (Exit mode 0)\n",
      "            Current function value: 0.2809512631584162\n",
      "            Iterations: 94\n",
      "            Function evaluations: 95\n",
      "            Gradient evaluations: 94\n",
      "Optimization terminated successfully.\n",
      "         Current function value: 0.259463\n",
      "         Iterations 7\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\stats\\_distn_infrastructure.py:879: RuntimeWarning: invalid value encountered in greater\n",
      "  return (self.a < x) & (x < self.b)\n",
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\stats\\_distn_infrastructure.py:879: RuntimeWarning: invalid value encountered in less\n",
      "  return (self.a < x) & (x < self.b)\n",
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\stats\\_distn_infrastructure.py:1821: RuntimeWarning: invalid value encountered in less_equal\n",
      "  cond2 = cond0 & (x <= self.a)\n",
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:931: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
      "d:\\ProgramData\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:869: FutureWarning: 'pred' is both an index level and a column label.\n",
      "Defaulting to column, but this will raise an ambiguity error in a future version\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(array([   8.,    8.,    7.,    6.,   11.,   14.,    8.,   26.,   17.,\n",
       "          26.,   27.,   24.,   20.,   22.,   21.,    8.,   40.,   30.,\n",
       "          22.,   44.,   13.,   13.,   33.,   32.,   13.,   19.,   20.,\n",
       "           2.,   22.,   22.,    8.,   10.,   18.,   10.,   29.,   35.,\n",
       "          23.,   50.,   35.,   47.,   60.,  100.,   67.,  144.,  147.,\n",
       "         162.,  216.,  219.,  126.,  244.,  304.,   76.,  191.,  368.,\n",
       "          95.,  202.,  296.,   69.,  171.,  263.,   89.,  153.,  368.,\n",
       "          92.,  149.,  331.,  115.,  229.,  360.,  294.,  496.,  801.,\n",
       "         829., 1028., 1078., 1263.,  578., 1261.,  503., 1747., 1096.,\n",
       "         663.,  590.,  860.,  290.,  913., 1152.,  440., 1333., 1014.,\n",
       "         637.,  736.,  521.,  400.,  425.,  397.,  159.,  130.,  120.,\n",
       "          96.]),\n",
       " array([106.  , 113.67, 121.34, 129.01, 136.68, 144.35, 152.02, 159.69,\n",
       "        167.36, 175.03, 182.7 , 190.37, 198.04, 205.71, 213.38, 221.05,\n",
       "        228.72, 236.39, 244.06, 251.73, 259.4 , 267.07, 274.74, 282.41,\n",
       "        290.08, 297.75, 305.42, 313.09, 320.76, 328.43, 336.1 , 343.77,\n",
       "        351.44, 359.11, 366.78, 374.45, 382.12, 389.79, 397.46, 405.13,\n",
       "        412.8 , 420.47, 428.14, 435.81, 443.48, 451.15, 458.82, 466.49,\n",
       "        474.16, 481.83, 489.5 , 497.17, 504.84, 512.51, 520.18, 527.85,\n",
       "        535.52, 543.19, 550.86, 558.53, 566.2 , 573.87, 581.54, 589.21,\n",
       "        596.88, 604.55, 612.22, 619.89, 627.56, 635.23, 642.9 , 650.57,\n",
       "        658.24, 665.91, 673.58, 681.25, 688.92, 696.59, 704.26, 711.93,\n",
       "        719.6 , 727.27, 734.94, 742.61, 750.28, 757.95, 765.62, 773.29,\n",
       "        780.96, 788.63, 796.3 , 803.97, 811.64, 819.31, 826.98, 834.65,\n",
       "        842.32, 849.99, 857.66, 865.33, 873.  ]),\n",
       " <a list of 100 Patch objects>)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import pickle\n",
    "from statsmodels.stats.outliers_influence import variance_inflation_factor\n",
    "import statsmodels.api as sm\n",
    "from sklearn import ensemble\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from sklearn.metrics import roc_auc_score\n",
    "\n",
    "'''\n",
    "时间：20190227\n",
    "作者：小象学院\n",
    "'''\n",
    " \n",
    "#################################\n",
    "#由于数据已经经过一定的清洗了，非一手数据，所以我们忽略了一些步骤，进行变量衍生\n",
    "#   1, 读取数据，衍生初始变量   #\n",
    "'''\n",
    "Loan_Amount:总额度\n",
    "OS：未还金额\n",
    "Payment：还款金额\n",
    "Spend：使用金额\n",
    "Delq：逾期情况\n",
    "'''\n",
    "#################################\n",
    "folderOfData = 'D:\\\\shaojie\\\\NutsCloud\\\\Teach'\n",
    "trainData = pd.read_csv(folderOfData+'/训练集.csv',header = 0,engine ='python')\n",
    "testData = pd.read_csv(folderOfData+'/测试集.csv',header = 0,engine ='python')\n",
    "\n",
    "\n",
    "# 衍生逾期类型的特征的函数\n",
    "def DelqFeatures(event,window,type):\n",
    "    '''\n",
    "    :parms event 数据框\n",
    "    :parms windows 时间窗口\n",
    "    :parms type 响应事件类型\n",
    "    '''\n",
    "    current = 12\n",
    "    start = 12 - window + 1\n",
    "    #delq1、delq2、delq3为了获取window相对应的dataframe范围\n",
    "    delq1 = [event[a] for a in ['Delq1_' + str(t) for t in range(current, start - 1, -1)]]\n",
    "    delq2 = [event[a] for a in ['Delq2_' + str(t) for t in range(current, start - 1, -1)]]\n",
    "    delq3 = [event[a] for a in ['Delq3_' + str(t) for t in range(current, start - 1, -1)]]\n",
    "    if type == 'max delq':\n",
    "        if max(delq3) == 1:\n",
    "            return 3\n",
    "        elif max(delq2) == 1:\n",
    "            return 2\n",
    "        elif max(delq1) == 1:\n",
    "            return 1\n",
    "        else:\n",
    "            return 0\n",
    "    if type in ['M0 times','M1 times', 'M2 times']:\n",
    "        if type.find('M0')>-1:\n",
    "            return sum(delq1)\n",
    "        elif type.find('M1')>-1:\n",
    "            return sum(delq2)\n",
    "        else:\n",
    "            return sum(delq3)\n",
    "\n",
    "allFeatures = []\n",
    " \n",
    "'''\n",
    "逾期类型的特征在行为评分卡（预测违约行为）中，一般是非常显著的变量。\n",
    "通过设定时间窗口，可以衍生以下类型的逾期变量：\n",
    "'''\n",
    " \n",
    "# 考虑过去1个月，3个月，6个月，12个月\n",
    "for t in [1,3,6,12]:\n",
    "    # 1，过去t时间窗口内的最大逾期状态\n",
    "    allFeatures.append('maxDelqL'+str(t)+\"M\")\n",
    "    trainData['maxDelqL'+str(t)+\"M\"] = trainData.apply(lambda x: DelqFeatures(x,t,'max delq'),axis=1)\n",
    " \n",
    "    # 2，过去t时间窗口内的，M0,M1,M2的次数\n",
    "    allFeatures.append('M0FreqL' + str(t) + \"M\")\n",
    "    trainData['M0FreqL' + str(t) + \"M\"] = trainData.apply(lambda x: DelqFeatures(x,t,'M0 times'),axis=1)\n",
    " \n",
    "    allFeatures.append('M1FreqL' + str(t) + \"M\")\n",
    "    trainData['M1FreqL' + str(t) + \"M\"] = trainData.apply(lambda x: DelqFeatures(x, t, 'M1 times'), axis=1)\n",
    " \n",
    "    allFeatures.append('M2FreqL' + str(t) + \"M\")\n",
    "    trainData['M2FreqL' + str(t) + \"M\"] = trainData.apply(lambda x: DelqFeatures(x, t, 'M2 times'), axis=1)\n",
    " \n",
    " \n",
    "\n",
    "#衍生额度使用率类型特征的函数\n",
    "def UrateFeatures(event, window, type):\n",
    "    '''\n",
    "    :parms event 数据框\n",
    "    :parms windows 时间窗口\n",
    "    :parms type 响应事件类型\n",
    "    '''\n",
    "    current = 12\n",
    "    start = 12 - window + 1\n",
    "    #获取在数据框内有效区域\n",
    "    monthlySpend = [event[a] for a in ['Spend_' + str(t) for t in range(current, start - 1, -1)]]\n",
    "    #获取授信总额度\n",
    "    limit = event['Loan_Amount']\n",
    "    #月使用率\n",
    "    monthlyUrate = [x / limit for x in monthlySpend]\n",
    "    if type == 'mean utilization rate':\n",
    "        return np.mean(monthlyUrate)\n",
    "    if type == 'max utilization rate':\n",
    "        return max(monthlyUrate)\n",
    "    #月额度使用率增加的月份\n",
    "    if type == 'increase utilization rate':\n",
    "        #val[0:-1]表示第一个元素到倒数第二个元素的切片\n",
    "        currentUrate = monthlyUrate[0:-1]\n",
    "        #val[1:]表示第二个元素到最后一个元素的切片\n",
    "        previousUrate = monthlyUrate[1:]\n",
    "        compareUrate = [int(x[0]>x[1]) for x in zip(currentUrate,previousUrate)]\n",
    "        return sum(compareUrate)\n",
    "\n",
    "\n",
    "'''\n",
    "额度使用率类型特征在行为评分卡模型中，通常是与违约高度相关的\n",
    "'''\n",
    "# 考虑过去1个月，3个月，6个月，12个月\n",
    "for t in [1,3,6,12]:\n",
    "    # 1，过去t时间窗口内的最大月额度使用率\n",
    "    allFeatures.append('maxUrateL' + str(t) + \"M\")\n",
    "    trainData['maxUrateL' + str(t) + \"M\"] = trainData.apply(lambda x: UrateFeatures(x,t,'max utilization rate'),axis = 1)\n",
    " \n",
    "    # 2，过去t时间窗口内的平均月额度使用率\n",
    "    allFeatures.append('avgUrateL' + str(t) + \"M\")\n",
    "    trainData['avgUrateL' + str(t) + \"M\"] = trainData.apply(lambda x: UrateFeatures(x, t, 'mean utilization rate'),axis=1)\n",
    " \n",
    "    # 3，过去t时间窗口内，月额度使用率增加的月份。该变量要求t>1\n",
    "    if t > 1:\n",
    "        allFeatures.append('increaseUrateL' + str(t) + \"M\")\n",
    "        trainData['increaseUrateL' + str(t) + \"M\"] = trainData.apply(lambda x: UrateFeatures(x, t, 'increase utilization rate'),axis=1)\n",
    " \n",
    " \n",
    "#衍生还款类型特征的函数\n",
    "def PaymentFeatures(event, window, type):\n",
    "    current = 12\n",
    "    start = 12 - window + 1\n",
    "    #月还款金额\n",
    "    currentPayment = [event[a] for a in ['Payment_' + str(t) for t in range(current, start - 1, -1)]]\n",
    "    #月使用金额，错位一下\n",
    "    previousOS = [event[a] for a in ['OS_' + str(t) for t in range(current-1, start - 2, -1)]]\n",
    "    monthlyPayRatio = []\n",
    "    for Pay_OS in zip(currentPayment,previousOS):\n",
    "        #前一个月使用了才会产生还款\n",
    "        if Pay_OS[1]>0:\n",
    "            payRatio = Pay_OS[0]*1.0 / Pay_OS[1]\n",
    "            monthlyPayRatio.append(payRatio)\n",
    "        #前一个月没使用，就按照100%还款\n",
    "        else:\n",
    "            monthlyPayRatio.append(1)\n",
    "    if type == 'min payment ratio':\n",
    "        return min(monthlyPayRatio)\n",
    "    if type == 'max payment ratio':\n",
    "        return max(monthlyPayRatio)\n",
    "    if type == 'mean payment ratio':\n",
    "        total_payment = sum(currentPayment)\n",
    "        total_OS = sum(previousOS)\n",
    "        if total_OS > 0:\n",
    "            return total_payment / total_OS\n",
    "        else:\n",
    "            return 1\n",
    "\n",
    "'''\n",
    "还款类型特征也是行为评分卡模型中常用的特征\n",
    "'''\n",
    "# 考虑过去1个月，3个月，6个月，12个月\n",
    "for t in [1,3,6,12]:\n",
    "    # 1，过去t时间窗口内的最大月还款率\n",
    "    allFeatures.append('maxPayL' + str(t) + \"M\")\n",
    "    trainData['maxPayL' + str(t) + \"M\"] = trainData.apply(lambda x: PaymentFeatures(x, t, 'max payment ratio'),axis=1)\n",
    "    # 2，过去t时间窗口内的最小月还款率\n",
    "    allFeatures.append('minPayL' + str(t) + \"M\")\n",
    "    trainData['minPayL' + str(t) + \"M\"] = trainData.apply(lambda x: PaymentFeatures(x, t, 'min payment ratio'),axis=1)\n",
    "    # 3，过去t时间窗口内的平均月还款率\n",
    "    allFeatures.append('avgPayL' + str(t) + \"M\")\n",
    "    trainData['avgPayL' + str(t) + \"M\"] = trainData.apply(lambda x: PaymentFeatures(x, t, 'mean payment ratio'),axis=1)\n",
    "\n",
    "\n",
    "\n",
    "###函数########\n",
    "#计算变量分箱之后各分箱的坏样本率\n",
    "def BinBadRate(df, col, target, grantRateIndicator=0):\n",
    "    '''\n",
    "    :param df: 需要计算好坏比率的数据集\n",
    "    :param col: 需要计算好坏比率的特征\n",
    "    :param target: 好坏标签\n",
    "    :param grantRateIndicator: 1返回总体的坏样本率，0不返回\n",
    "    :return: 每箱的坏样本率，以及总体的坏样本率（当grantRateIndicator＝＝1时）\n",
    "    '''\n",
    "    #print(df.groupby([col])[target])\n",
    "    total = df.groupby([col])[target].count()\n",
    "    #print(total)\n",
    "    total = pd.DataFrame({'total': total})\n",
    "    #print(total)\n",
    "    bad = df.groupby([col])[target].sum()\n",
    "    bad = pd.DataFrame({'bad': bad})\n",
    "    #合并\n",
    "    regroup = total.merge(bad, left_index=True, right_index=True, how='left')\n",
    "    #print(regroup)\n",
    "    regroup.reset_index(level=0, inplace=True)\n",
    "    #print(regroup)\n",
    "    #计算坏样本率\n",
    "    regroup['bad_rate'] = regroup.apply(lambda x: x.bad * 1.0 / x.total, axis=1)\n",
    "    #print(regroup)\n",
    "    #生成字典，（变量名取值：坏样本率）\n",
    "    dicts = dict(zip(regroup[col],regroup['bad_rate']))\n",
    "    if grantRateIndicator==0:\n",
    "        return (dicts, regroup)\n",
    "    N = sum(regroup['total'])\n",
    "    B = sum(regroup['bad'])\n",
    "    #总体样本率\n",
    "    overallRate = B * 1.0 / N\n",
    "    return (dicts, regroup, overallRate)\n",
    "\n",
    "\n",
    "## 判断某变量的坏样本率是否单调\n",
    "def BadRateMonotone(df, sortByVar, target,special_attribute = []):\n",
    "    '''\n",
    "    :param df: 包含检验坏样本率的变量，和目标变量\n",
    "    :param sortByVar: 需要检验坏样本率的变量\n",
    "    :param target: 目标变量，0、1表示好、坏\n",
    "    :param special_attribute: 不参与检验的特殊值\n",
    "    :return: 坏样本率单调与否\n",
    "    '''\n",
    "    df2 = df.loc[~df[sortByVar].isin(special_attribute)]\n",
    "    if len(set(df2[sortByVar])) <= 2:\n",
    "        return True\n",
    "    regroup = BinBadRate(df2, sortByVar, target)[1]\n",
    "    combined = zip(regroup['total'],regroup['bad'])\n",
    "    badRate = [x[1]*1.0/x[0] for x in combined]\n",
    "    badRateNotMonotone = [badRate[i]<badRate[i+1] and badRate[i] < badRate[i-1] or badRate[i]>badRate[i+1] and badRate[i] > badRate[i-1]\n",
    "                          for i in range(1,len(badRate)-1)]\n",
    "    if True in badRateNotMonotone:\n",
    "        return False\n",
    "    else:\n",
    "        return True\n",
    " \n",
    " \n",
    "############################\n",
    "#   2, 分箱，计算WOE并编码   #\n",
    "############################\n",
    "\n",
    "'''\n",
    "对类别型变量的分箱和WOE计算\n",
    "可以通过计算取值个数的方式判断是否是类别型变量\n",
    "'''\n",
    "#类别型变量\n",
    "categoricalFeatures = []\n",
    "#连续型变量\n",
    "numericalFeatures = []\n",
    "WOE_IV_dict = {}\n",
    "for var in allFeatures:\n",
    "    if len(set(trainData[var])) > 5:\n",
    "        numericalFeatures.append(var)\n",
    "    else:\n",
    "        categoricalFeatures.append(var)\n",
    "\n",
    "not_monotone =[]\n",
    "for var in categoricalFeatures:\n",
    "    #检查bad rate在箱中的单调性\n",
    "    if not BadRateMonotone(trainData, var, 'label'):\n",
    "        not_monotone.append(var)\n",
    "\n",
    "#print(\"数值取值小于5类别型变量{}坏样本率不单调\".format(not_monotone))\n",
    " \n",
    "# 'M1FreqL3M'，'M2FreqL3M', 'maxDelqL12M' 是不单调的，需要合并其中某些类别\n",
    "trainData.groupby(['M2FreqL3M'])['label'].mean()  #检查单调性\n",
    "trainData.groupby(['M2FreqL3M'])['label'].count()   #其中，M2FreqL3M＝3总共只有3个样本，因此要进行合并\n",
    " \n",
    " \n",
    " \n",
    "# 将 M2FreqL3M>=1的合并为一组，计算WOE和IV\n",
    "trainData['M2FreqL3M_Bin'] = trainData['M2FreqL3M'].apply(lambda x: int(x>=1))\n",
    "trainData.groupby(['M2FreqL3M_Bin'])['label'].mean()\n",
    " \n",
    " \n",
    " \n",
    "#计算WOE值\n",
    "def CalcWOE(df, col, target):\n",
    "    '''\n",
    "    :param df: 包含需要计算WOE的变量和目标变量\n",
    "    :param col: 需要计算WOE、IV的变量，必须是分箱后的变量，或者不需要分箱的类别型变量\n",
    "    :param target: 目标变量，0、1表示好、坏\n",
    "    :return: 返回WOE和IV\n",
    "    '''\n",
    "    total = df.groupby([col])[target].count()\n",
    "    total = pd.DataFrame({'total': total})\n",
    "    bad = df.groupby([col])[target].sum()\n",
    "    bad = pd.DataFrame({'bad': bad})\n",
    "    regroup = total.merge(bad, left_index=True, right_index=True, how='left')\n",
    "    regroup.reset_index(level=0, inplace=True)\n",
    "    N = sum(regroup['total'])\n",
    "    B = sum(regroup['bad'])\n",
    "    regroup['good'] = regroup['total'] - regroup['bad']\n",
    "    G = N - B\n",
    "    regroup['bad_pcnt'] = regroup['bad'].map(lambda x: x*1.0/B)\n",
    "    regroup['good_pcnt'] = regroup['good'].map(lambda x: x * 1.0 / G)\n",
    "    regroup['WOE'] = regroup.apply(lambda x: np.log(x.good_pcnt*1.0/x.bad_pcnt),axis = 1)\n",
    "    WOE_dict = regroup[[col,'WOE']].set_index(col).to_dict(orient='index')\n",
    "    for k, v in WOE_dict.items():\n",
    "        WOE_dict[k] = v['WOE']\n",
    "    IV = regroup.apply(lambda x: (x.good_pcnt-x.bad_pcnt)*np.log(x.good_pcnt*1.0/x.bad_pcnt),axis = 1)\n",
    "    IV = sum(IV)\n",
    "    return {\"WOE\": WOE_dict, 'IV':IV}\n",
    "WOE_IV_dict['M2FreqL3M_Bin'] = CalcWOE(trainData, 'M2FreqL3M_Bin', 'label')\n",
    " \n",
    "trainData.groupby(['M1FreqL3M'])['label'].mean()  #检查单调性\n",
    "trainData.groupby(['M1FreqL3M'])['label'].count()\n",
    " \n",
    "# 除了M1FreqL3M＝3外， 其他组别的bad rate单调。\n",
    "# 此外，M1FreqL3M＝0 占比很大，因此将M1FreqL3M>=1的分为一组\n",
    "trainData['M1FreqL3M_Bin'] = trainData['M1FreqL3M'].apply(lambda x: int(x>=1))\n",
    "trainData.groupby(['M1FreqL3M_Bin'])['label'].mean()\n",
    "WOE_IV_dict['M1FreqL3M_Bin'] = CalcWOE(trainData, 'M1FreqL3M_Bin', 'label')\n",
    " \n",
    "'''\n",
    "对其他单调的类别型变量，检查是否有一箱的占比低于5%。 如果有，将该变量进行合并\n",
    "'''\n",
    "small_bin_var = []\n",
    "large_bin_var = []\n",
    "N = trainData.shape[0]\n",
    "for var in categoricalFeatures:\n",
    "    if var not in not_monotone:\n",
    "        total = trainData.groupby([var])[var].count()\n",
    "        pcnt = total * 1.0 / N\n",
    "        if min(pcnt)<0.05:\n",
    "            small_bin_var.append({var:pcnt.to_dict()})\n",
    "        else:\n",
    "            large_bin_var.append(var)\n",
    " \n",
    " \n",
    "#对于M2FreqL1M、M2FreqL6M和M2FreqL12M，由于有部分箱占了很大比例，故删除，因为样本表现99%都一样，这个变量没有区分度\n",
    "allFeatures.remove('M2FreqL1M')\n",
    "allFeatures.remove('M2FreqL6M')\n",
    "allFeatures.remove('M2FreqL12M')\n",
    " \n",
    "def MergeByCondition(x,condition_list):\n",
    "    #condition_list是条件列表。满足第几个condition，就输出几\n",
    "    s = 0\n",
    "    for condition in condition_list:\n",
    "        if eval(str(x)+condition):\n",
    "            return s\n",
    "        else:\n",
    "            s+=1\n",
    "    return s\n",
    " \n",
    "#对于small_bin_var中的其他变量，将最小的箱和相邻的箱进行合并并计算WOE\n",
    "trainData['maxDelqL1M_Bin'] = trainData['maxDelqL1M'].apply(lambda x: MergeByCondition(x,['==0','==1','>=2']))\n",
    "trainData['maxDelqL3M_Bin'] = trainData['maxDelqL3M'].apply(lambda x: MergeByCondition(x,['==0','==1','>=2']))\n",
    "trainData['maxDelqL6M_Bin'] = trainData['maxDelqL6M'].apply(lambda x: MergeByCondition(x,['==0','==1','>=2']))\n",
    "for var in ['maxDelqL1M_Bin','maxDelqL3M_Bin','maxDelqL6M_Bin']:\n",
    "    WOE_IV_dict[var] = CalcWOE(trainData, var, 'label')\n",
    " \n",
    " \n",
    "'''\n",
    "对于不需要合并、原始箱的bad rate单调的特征，直接计算WOE和IV\n",
    "'''\n",
    "for var in large_bin_var:\n",
    "    WOE_IV_dict[var] = CalcWOE(trainData, var, 'label')\n",
    " \n",
    " \n",
    "def AssignBin(x, cutOffPoints,special_attribute=[]):\n",
    "    '''\n",
    "    :param x: 某个变量的某个取值\n",
    "    :param cutOffPoints: 上述变量的分箱结果，用切分点表示\n",
    "    :param special_attribute:  不参与分箱的特殊取值\n",
    "    :return: 分箱后的对应的第几个箱，从0开始\n",
    "    for example, if cutOffPoints = [10,20,30], if x = 7, return Bin 0. If x = 35, return Bin 3\n",
    "    '''\n",
    "    numBin = len(cutOffPoints) + 1 + len(special_attribute)\n",
    "    if x in special_attribute:\n",
    "        i = special_attribute.index(x)+1\n",
    "        return 'Bin {}'.format(0-i)\n",
    "    if x<=cutOffPoints[0]:\n",
    "        return 'Bin 0'\n",
    "    elif x > cutOffPoints[-1]:\n",
    "        return 'Bin {}'.format(numBin-1)\n",
    "    else:\n",
    "        for i in range(0,numBin-1):\n",
    "            if cutOffPoints[i] < x <=  cutOffPoints[i+1]:\n",
    "                return 'Bin {}'.format(i+1)\n",
    "\n",
    "\n",
    "\n",
    "def AssignGroup(x, bin):\n",
    "    '''\n",
    "    :param x: 某个变量的某个取值\n",
    "    :param bin: 上述变量的分箱结果\n",
    "    :return: x在分箱结果下的映射\n",
    "    '''\n",
    "    N = len(bin)\n",
    "    if x<=min(bin):\n",
    "        return min(bin)\n",
    "    elif x>max(bin):\n",
    "        return 10e10\n",
    "    else:\n",
    "        for i in range(N-1):\n",
    "            if bin[i] < x <= bin[i+1]:\n",
    "                return bin[i+1]\n",
    " \n",
    " \n",
    "def SplitData(df, col, numOfSplit, special_attribute=[]):\n",
    "    '''\n",
    "    :param df: 按照col排序后的数据集\n",
    "    :param col: 待分箱的变量\n",
    "    :param numOfSplit: 切分的组别数\n",
    "    :param special_attribute: 在切分数据集的时候，某些特殊值需要排除在外\n",
    "    :return: 在原数据集上增加一列，把原始细粒度的col重新划分成粗粒度的值，便于分箱中的合并处理\n",
    "    '''\n",
    "    df2 = df.copy()\n",
    "    if special_attribute != []:\n",
    "        df2 = df.loc[~df[col].isin(special_attribute)]\n",
    "    N = df2.shape[0]#行数\n",
    "    #\" / \"就表示 浮点数除法，返回浮点结果;\" // \"表示整数除法\n",
    "    n = N//numOfSplit #每组样本数\n",
    "    splitPointIndex = [i*n for i in range(1,numOfSplit)] #分割点的下标\n",
    "    '''\n",
    "    [i*2 for i in range(1,100)]\n",
    "    [2, 4, 6, 8, 10,......,198]\n",
    "    '''\n",
    "    rawValues = sorted(list(df2[col])) #对取值进行排序\n",
    "    #取到粗糙卡方划分节点\n",
    "    splitPoint = [rawValues[i] for i in splitPointIndex] #分割点的取值\n",
    "    splitPoint = sorted(list(set(splitPoint)))\n",
    "    return splitPoint\n",
    "\n",
    "\n",
    "#计算卡方值的函数\n",
    "def Chi2(df, total_col, bad_col, overallRate):\n",
    "    '''\n",
    "    :param df: 包含全部样本总计与坏样本总计的数据框\n",
    "    :param total_col: 全部样本的个数\n",
    "    :param bad_col: 坏样本的个数\n",
    "    :param overallRate: 全体样本的坏样本占比\n",
    "    :return: 卡方值\n",
    "    '''\n",
    "    df2 = df.copy()\n",
    "    # 期望坏样本个数＝全部样本个数*平均坏样本占比\n",
    "    df2['expected'] = df[total_col].apply(lambda x: x*overallRate)\n",
    "    combined = zip(df2['expected'], df2[bad_col])\n",
    "    chi = [(i[0]-i[1])**2/i[0] for i in combined]\n",
    "    chi2 = sum(chi)\n",
    "    return chi2\n",
    "\n",
    "\n",
    "##ChiMerge_MaxInterval：通过指定最大间隔数，使用卡方值分割连续变量\n",
    "def ChiMerge(df, col, target, max_interval=5,special_attribute=[],minBinPcnt=0):\n",
    "    '''\n",
    "    :param df: 包含目标变量与分箱属性的数据框\n",
    "    :param col: 需要分箱的属性\n",
    "    :param target: 目标变量，取值0或1\n",
    "    :param max_interval: 最大分箱数。如果原始属性的取值个数低于该参数，不执行这段函数\n",
    "    :param special_attribute: 不参与分箱的属性取值，缺失值的情况\n",
    "    :param minBinPcnt：最小箱的占比，默认为0\n",
    "    :return: 分箱结果\n",
    "    '''\n",
    "    colLevels = sorted(list(set(df[col])))\n",
    "    N_distinct = len(colLevels)#不同的取值个数\n",
    "    if N_distinct <= max_interval:  #如果原始属性的取值个数低于max_interval，不执行这段函数\n",
    "        print (\"原始属性{}的取值个数低于max_interval\".format(col))\n",
    "        #分箱分数间隔段，少一个值也可以\n",
    "        #返回值colLevels会少一个最大值\n",
    "        return colLevels[:-1]\n",
    "    else:\n",
    "        if len(special_attribute)>=1:\n",
    "            #df1数据框取trainData中col那一列为特殊值的数据集\n",
    "            #df1 = df.loc[df[col].isin(special_attribute)]\n",
    "            print('{} 有缺失值的情况'.format(col))\n",
    "            #用逆函数对筛选后的结果取余，起删除指定行作用\n",
    "            df2 = df.loc[~df[col].isin(special_attribute)]\n",
    "        else:\n",
    "            df2 = df.copy()\n",
    "        N_distinct = len(list(set(df2[col])))#该特征不同的取值\n",
    " \n",
    "        # 步骤一: 通过col对数据集进行分组，求出每组的总样本数与坏样本数\n",
    "        if N_distinct > 100:\n",
    "            '''\n",
    "            split_x样例\n",
    "            [2, 8, 9.3 , 1 0, 30 ,......,1800]\n",
    "            '''\n",
    "            split_x = SplitData(df2, col, 100)\n",
    "            #把值变为划分点的值\n",
    "            df2['temp'] = df2[col].map(lambda x: AssignGroup(x, split_x))\n",
    "        else:\n",
    "            #假如数值取值小于100就不发生变化了\n",
    "            df2['temp'] = df2[col]\n",
    "        # 总体bad rate将被用来计算expected bad count\n",
    "        (binBadRate, regroup, overallRate) = BinBadRate(df2, 'temp', target, grantRateIndicator=1)\n",
    " \n",
    "        # 首先，每个单独的属性值将被分为单独的一组\n",
    "        # 对属性值进行排序，然后两两组别进行合并\n",
    "        colLevels = sorted(list(set(df2['temp'])))\n",
    "        groupIntervals = [[i] for i in colLevels]\n",
    " \n",
    "        # 步骤二：建立循环，不断合并最优的相邻两个组别，直到：\n",
    "        # 1，最终分裂出来的分箱数<＝预设的最大分箱数\n",
    "        # 2，每箱的占比不低于预设值（可选）\n",
    "        # 3，每箱同时包含好坏样本\n",
    "        # 如果有特殊属性，那么最终分裂出来的分箱数＝预设的最大分箱数－特殊属性的个数\n",
    "        split_intervals = max_interval - len(special_attribute)\n",
    "        while (len(groupIntervals) > split_intervals):  # 终止条件: 当前分箱数＝预设的分箱数\n",
    "            # 每次循环时, 计算合并相邻组别后的卡方值。具有最小卡方值的合并方案，是最优方案\n",
    "            #存储卡方值\n",
    "            chisqList = []\n",
    "            for k in range(len(groupIntervals)-1):\n",
    "                temp_group = groupIntervals[k] + groupIntervals[k+1]\n",
    "                df2b = regroup.loc[regroup['temp'].isin(temp_group)]\n",
    "                chisq = Chi2(df2b, 'total', 'bad', overallRate)\n",
    "                chisqList.append(chisq)\n",
    "            best_comnbined = chisqList.index(min(chisqList))\n",
    "            groupIntervals[best_comnbined] = groupIntervals[best_comnbined] + groupIntervals[best_comnbined+1]\n",
    "            # after combining two intervals, we need to remove one of them\n",
    "            groupIntervals.remove(groupIntervals[best_comnbined+1])\n",
    "        groupIntervals = [sorted(i) for i in groupIntervals]\n",
    "        cutOffPoints = [max(i) for i in groupIntervals[:-1]]\n",
    " \n",
    "        # 检查是否有箱没有好或者坏样本。如果有，需要跟相邻的箱进行合并，直到每箱同时包含好坏样本\n",
    "        groupedvalues = df2['temp'].apply(lambda x: AssignBin(x, cutOffPoints))\n",
    "        #已成完成卡方分箱，但是没有考虑其单调性\n",
    "        df2['temp_Bin'] = groupedvalues\n",
    "        (binBadRate,regroup) = BinBadRate(df2, 'temp_Bin', target)\n",
    "        [minBadRate, maxBadRate] = [min(binBadRate.values()),max(binBadRate.values())]\n",
    "        while minBadRate ==0 or maxBadRate == 1:\n",
    "            # 找出全部为好／坏样本的箱\n",
    "            indexForBad01 = regroup[regroup['bad_rate'].isin([0,1])].temp_Bin.tolist()\n",
    "            bin=indexForBad01[0]\n",
    "            # 如果是最后一箱，则需要和上一个箱进行合并，也就意味着分裂点cutOffPoints中的最后一个需要移除\n",
    "            if bin == max(regroup.temp_Bin):\n",
    "                cutOffPoints = cutOffPoints[:-1]\n",
    "            # 如果是第一箱，则需要和下一个箱进行合并，也就意味着分裂点cutOffPoints中的第一个需要移除\n",
    "            elif bin == min(regroup.temp_Bin):\n",
    "                cutOffPoints = cutOffPoints[1:]\n",
    "            # 如果是中间的某一箱，则需要和前后中的一个箱进行合并，依据是较小的卡方值\n",
    "            else:\n",
    "                # 和前一箱进行合并，并且计算卡方值\n",
    "                currentIndex = list(regroup.temp_Bin).index(bin)\n",
    "                prevIndex = list(regroup.temp_Bin)[currentIndex - 1]\n",
    "                df3 = df2.loc[df2['temp_Bin'].isin([prevIndex, bin])]\n",
    "                (binBadRate, df2b) = BinBadRate(df3, 'temp_Bin', target)\n",
    "                chisq1 = Chi2(df2b, 'total', 'bad', overallRate)\n",
    "                # 和后一箱进行合并，并且计算卡方值\n",
    "                laterIndex = list(regroup.temp_Bin)[currentIndex + 1]\n",
    "                df3b = df2.loc[df2['temp_Bin'].isin([laterIndex, bin])]\n",
    "                (binBadRate, df2b) = BinBadRate(df3b, 'temp_Bin', target)\n",
    "                chisq2 = Chi2(df2b, 'total', 'bad', overallRate)\n",
    "                if chisq1 < chisq2:\n",
    "                    cutOffPoints.remove(cutOffPoints[currentIndex - 1])\n",
    "                else:\n",
    "                    cutOffPoints.remove(cutOffPoints[currentIndex])\n",
    "            # 完成合并之后，需要再次计算新的分箱准则下，每箱是否同时包含好坏样本\n",
    "            groupedvalues = df2['temp'].apply(lambda x: AssignBin(x, cutOffPoints))\n",
    "            df2['temp_Bin'] = groupedvalues\n",
    "            (binBadRate, regroup) = BinBadRate(df2, 'temp_Bin', target)\n",
    "            [minBadRate, maxBadRate] = [min(binBadRate.values()), max(binBadRate.values())]\n",
    " \n",
    "        # 需要检查分箱后的最小占比\n",
    "        if minBinPcnt > 0:\n",
    "            groupedvalues = df2['temp'].apply(lambda x: AssignBin(x, cutOffPoints))\n",
    "            df2['temp_Bin'] = groupedvalues\n",
    "            #value_counts每个数值出现了多少次\n",
    "            valueCounts = groupedvalues.value_counts().to_frame()\n",
    "            N=sum(valueCounts['temp'])\n",
    "            valueCounts['pcnt'] = valueCounts['temp'].apply(lambda x: x * 1.0 / N)\n",
    "            valueCounts = valueCounts.sort_index()\n",
    "            minPcnt = min(valueCounts['pcnt'])\n",
    "            #一定要箱数大于2才可以，要不就不能再合并了\n",
    "            while minPcnt < minBinPcnt and len(cutOffPoints) > 2:\n",
    "                # 找出占比最小的箱\n",
    "                indexForMinPcnt = valueCounts[valueCounts['pcnt'] == minPcnt].index.tolist()[0]\n",
    "                # 如果占比最小的箱是最后一箱，则需要和上一个箱进行合并，也就意味着分裂点cutOffPoints中的最后一个需要移除\n",
    "                if indexForMinPcnt == max(valueCounts.index):\n",
    "                    cutOffPoints = cutOffPoints[:-1]\n",
    "                # 如果占比最小的箱是第一箱，则需要和下一个箱进行合并，也就意味着分裂点cutOffPoints中的第一个需要移除\n",
    "                elif indexForMinPcnt == min(valueCounts.index):\n",
    "                    cutOffPoints = cutOffPoints[1:]\n",
    "                # 如果占比最小的箱是中间的某一箱，则需要和前后中的一个箱进行合并，依据是较小的卡方值\n",
    "                else:\n",
    "                    # 和前一箱进行合并，并且计算卡方值\n",
    "                    currentIndex = list(valueCounts.index).index(indexForMinPcnt)\n",
    "                    prevIndex = list(valueCounts.index)[currentIndex - 1]\n",
    "                    df3 = df2.loc[df2['temp_Bin'].isin([prevIndex, indexForMinPcnt])]\n",
    "                    (binBadRate, df2b) = BinBadRate(df3, 'temp_Bin', target)\n",
    "                    chisq1 = Chi2(df2b, 'total', 'bad', overallRate)\n",
    "                    # 和后一箱进行合并，并且计算卡方值\n",
    "                    laterIndex = list(valueCounts.index)[currentIndex + 1]\n",
    "                    df3b = df2.loc[df2['temp_Bin'].isin([laterIndex, indexForMinPcnt])]\n",
    "                    (binBadRate, df2b) = BinBadRate(df3b, 'temp_Bin', target)\n",
    "                    chisq2 = Chi2(df2b, 'total', 'bad', overallRate)\n",
    "                    if chisq1 < chisq2:\n",
    "                        cutOffPoints.remove(cutOffPoints[currentIndex - 1])\n",
    "                    else:\n",
    "                        cutOffPoints.remove(cutOffPoints[currentIndex])\n",
    "        cutOffPoints = special_attribute + cutOffPoints\n",
    "        return cutOffPoints\n",
    "\n",
    "\n",
    "'''\n",
    "对于数值型变量，需要先分箱，再计算WOE、IV\n",
    "分箱的结果需要满足：\n",
    "1，箱数不超过5\n",
    "2，bad rate单调\n",
    "3，每箱占比不低于5%\n",
    "'''\n",
    "bin_dict = []\n",
    "for var in numericalFeatures:\n",
    "    binNum = 5\n",
    "    newBin = var + '_Bin'\n",
    "    bin = ChiMerge(trainData, var, 'label',max_interval=binNum,minBinPcnt = 0.05)\n",
    "    trainData[newBin] = trainData[var].apply(lambda x: AssignBin(x,bin))\n",
    "    # 如果不满足单调性，就降低分箱个数\n",
    "    while not BadRateMonotone(trainData, newBin, 'label'):\n",
    "        binNum -= 1\n",
    "        bin = ChiMerge(trainData, var, 'label', max_interval=binNum, minBinPcnt=0.05)\n",
    "        trainData[newBin] = trainData[var].apply(lambda x: AssignBin(x, bin))\n",
    "    WOE_IV_dict[newBin] = CalcWOE(trainData, newBin, 'label')\n",
    "    bin_dict.append({var:bin})\n",
    "\n",
    "\n",
    "\n",
    "##############################\n",
    "#   3, 单变量分析和多变量分析   #\n",
    "##############################\n",
    "#  选取IV高于0.02的变量\n",
    "high_IV = [(k,v['IV']) for k,v in WOE_IV_dict.items() if v['IV'] >= 0.02]\n",
    "high_IV_sorted = sorted(high_IV, key=lambda k: k[1],reverse=True)\n",
    "IV_values = [i[1] for i in high_IV_sorted]\n",
    "IV_name = [i[0] for i in high_IV_sorted]\n",
    "plt.title('High feature IV')\n",
    "plt.bar(range(len(IV_values)),IV_values)\n",
    "\n",
    "\n",
    "for (var,iv) in high_IV:\n",
    "    newVar = var+\"_WOE\"\n",
    "    trainData[newVar] = trainData[var].map(lambda x: WOE_IV_dict[var]['WOE'][x])\n",
    "\n",
    "\n",
    "saveFile = open(folderOfData+'/trainData.pkl','wb+')\n",
    "pickle.dump(trainData,saveFile)\n",
    "saveFile.close()\n",
    "\n",
    "\n",
    "saveFile = open(folderOfData+'/trainData.pkl','rb+')\n",
    "trainData = pickle.load(saveFile)\n",
    "saveFile.close()\n",
    "\n",
    "\n",
    "\n",
    "'''\n",
    "多变量分析：比较两两线性相关性。如果相关系数的绝对值高于阈值，剔除IV较低的一个\n",
    "'''\n",
    "deleted_index = []\n",
    "cnt_vars = len(high_IV_sorted)\n",
    "for i in range(cnt_vars):\n",
    "    if i in deleted_index:\n",
    "        continue\n",
    "    x1 = high_IV_sorted[i][0]+\"_WOE\"\n",
    "    for j in range(cnt_vars):\n",
    "        if i == j or j in deleted_index:\n",
    "            continue\n",
    "        y1 = high_IV_sorted[j][0]+\"_WOE\"\n",
    "        roh = np.corrcoef(trainData[x1],trainData[y1])[0,1]\n",
    "        if abs(roh)>0.7:\n",
    "            x1_IV = high_IV_sorted[i][1]\n",
    "            y1_IV = high_IV_sorted[j][1]\n",
    "            if x1_IV > y1_IV:\n",
    "                deleted_index.append(j)\n",
    "            else:\n",
    "                deleted_index.append(i)\n",
    "\n",
    "single_analysis_vars = [high_IV_sorted[i][0]+\"_WOE\" for i in range(cnt_vars) if i not in deleted_index]\n",
    "\n",
    "\n",
    "X = trainData[single_analysis_vars]\n",
    "f, ax = plt.subplots(figsize=(10, 8))\n",
    "corr = X.corr()\n",
    "sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool), cmap=sns.diverging_palette(220, 10, as_cmap=True),square=True, ax=ax)\n",
    "\n",
    "\n",
    "\n",
    "'''\n",
    "多变量分析：VIF\n",
    "'''\n",
    "X = np.matrix(trainData[single_analysis_vars])\n",
    "VIF_list = [variance_inflation_factor(X, i) for i in range(X.shape[1])]\n",
    "print(max(VIF_list))\n",
    "# 最大的VIF是 3.429，小于10，因此这一步认为没有多重共线性\n",
    "multi_analysis = single_analysis_vars\n",
    "\n",
    "\n",
    "################################\n",
    "#   4, 建立逻辑回归模型预测违约   #\n",
    "################################\n",
    "X = trainData[multi_analysis]\n",
    "#截距项\n",
    "X['intercept'] = [1] * X.shape[0]\n",
    "y = trainData['label']\n",
    "logit = sm.Logit(y, X)\n",
    "logit_result = logit.fit()\n",
    "pvalues = logit_result.pvalues\n",
    "params = logit_result.params\n",
    "fit_result = pd.concat([params,pvalues],axis=1)\n",
    "fit_result.columns = ['coef','p-value']\n",
    "fit_result = fit_result.sort_values(by = 'coef')\n",
    "\n",
    "'''\n",
    "                               coef        p-value\n",
    "intercept                 -1.812690   0.000000e+00\n",
    "increaseUrateL6M_Bin_WOE  -1.220508   2.620858e-62\n",
    "maxDelqL3M_Bin_WOE        -0.735785  3.600473e-163\n",
    "M2FreqL3M_Bin_WOE         -0.681009   1.284840e-63\n",
    "avgUrateL1M_Bin_WOE       -0.548608   2.350785e-07\n",
    "avgUrateL3M_Bin_WOE       -0.467298   8.870679e-05\n",
    "M0FreqL3M_WOE             -0.392261   2.386403e-26\n",
    "avgUrateL6M_Bin_WOE       -0.309831   3.028939e-02\n",
    "increaseUrateL3M_WOE      -0.300805   1.713878e-03\n",
    "maxUrateL3M_Bin_WOE       -0.213742   1.412028e-01\n",
    "avgPayL6M_Bin_WOE         -0.208924   4.241600e-07\n",
    "maxDelqL1M_Bin_WOE        -0.162785   1.835990e-07\n",
    "M1FreqL12M_Bin_WOE        -0.125595   2.576692e-03\n",
    "M1FreqL6M_Bin_WOE         -0.067979   8.572653e-02\n",
    "maxPayL6M_Bin_WOE         -0.063942   3.807461e-01\n",
    "maxUrateL6M_Bin_WOE       -0.056266   7.120434e-01\n",
    "avgPayL12M_Bin_WOE        -0.039538   4.487068e-01\n",
    "maxPayL12M_Bin_WOE         0.030780   8.135143e-01\n",
    "M0FreqL12M_Bin_WOE         0.077365   1.826047e-01\n",
    "minPayL6M_Bin_WOE          0.107868   3.441998e-01\n",
    "increaseUrateL12M_Bin_WOE  0.115845   4.292397e-01\n",
    "M0FreqL6M_Bin_WOE          0.145630   1.869349e-03\n",
    "minPayL3M_Bin_WOE          0.151294   4.293344e-02\n",
    "avgPayL1M_Bin_WOE          0.260946   6.606818e-04\n",
    "变量 \n",
    "maxPayL12M_Bin_WOE         0.030780   8.135143e-01\n",
    "M0FreqL12M_Bin_WOE         0.077365   1.826047e-01\n",
    "minPayL6M_Bin_WOE          0.107868   3.441998e-01\n",
    "increaseUrateL12M_Bin_WOE  0.115845   4.292397e-01\n",
    "M0FreqL6M_Bin_WOE          0.145630   1.869349e-03\n",
    "minPayL3M_Bin_WOE          0.151294   4.293344e-02\n",
    "avgPayL1M_Bin_WOE          0.260946   6.606818e-04\n",
    "的系数为正，需要单独检验\n",
    "'''\n",
    "\n",
    "sm.Logit(y, trainData['maxPayL12M_Bin_WOE']).fit().params  # -0.980206\n",
    "sm.Logit(y, trainData['M0FreqL12M_Bin_WOE']).fit().params  # -1.050918\n",
    "sm.Logit(y, trainData['minPayL6M_Bin_WOE']).fit().params  # -0.812302\n",
    "sm.Logit(y, trainData['increaseUrateL12M_Bin_WOE']).fit().params  #  -0.914707\n",
    "sm.Logit(y, trainData['M0FreqL6M_Bin_WOE']).fit().params  # -1.065785\n",
    "sm.Logit(y, trainData['minPayL3M_Bin_WOE']).fit().params  #  -0.819148\n",
    "sm.Logit(y, trainData['avgPayL1M_Bin_WOE']).fit().params  #  -1.007179\n",
    " \n",
    "# 单独建立回归模型，系数为负，与预期相符，说明仍然存在多重共线性\n",
    "# 下一步，用GBDT跑出变量重要性，挑选出合适的变量\n",
    "clf = ensemble.GradientBoostingClassifier()\n",
    "gbdt_model = clf.fit(X, y)\n",
    "importace = gbdt_model.feature_importances_.tolist()\n",
    "featureImportance = zip(multi_analysis,importace)\n",
    "featureImportanceSorted = sorted(featureImportance, key=lambda k: k[1],reverse=True)\n",
    "\n",
    "\n",
    "\n",
    "# 先假定模型可以容纳5个特征，再逐步增加特征个数，直到有特征的系数为正，或者p值超过0.1\n",
    "n = 5\n",
    "featureSelected = [i[0] for i in featureImportanceSorted[:n]]\n",
    "X_train = X[featureSelected+['intercept']]\n",
    "logit = sm.Logit(y, X_train)\n",
    "logit_result = logit.fit()\n",
    "pvalues = logit_result.pvalues\n",
    "params = logit_result.params\n",
    "fit_result = pd.concat([params,pvalues],axis=1)\n",
    "fit_result.columns = ['coef','p-value']\n",
    " \n",
    "while(n<len(featureImportanceSorted)):\n",
    "    nextVar = featureImportanceSorted[n][0]\n",
    "    featureSelected = featureSelected + [nextVar]\n",
    "    X_train = X[featureSelected+['intercept']]\n",
    "    logit = sm.Logit(y, X_train)\n",
    "    logit_result = logit.fit()\n",
    "    params = logit_result.params\n",
    "    #print(\"current var is \",nextVar,'   ', params[nextVar])\n",
    "    if max(params) < 0:\n",
    "        n += 1\n",
    "    else:\n",
    "        featureSelected.remove(nextVar)\n",
    "        n += 1\n",
    "\n",
    "X_train = X[featureSelected+['intercept']]\n",
    "logit = sm.Logit(y, X_train)\n",
    "logit_result = logit.fit()\n",
    "pvalues = logit_result.pvalues\n",
    "params = logit_result.params\n",
    "fit_result = pd.concat([params,pvalues],axis=1)\n",
    "fit_result.columns = ['coef','p-value']\n",
    "fit_result = fit_result.sort_values(by  = 'p-value')\n",
    "'''\n",
    "                              coef        p-value\n",
    "intercept                -1.809479   0.000000e+00\n",
    "maxDelqL3M_Bin_WOE       -0.762903  2.603323e-192\n",
    "increaseUrateL6M_Bin_WOE -1.194299   4.259502e-68\n",
    "M2FreqL3M_Bin_WOE        -0.684674   1.067350e-64\n",
    "M0FreqL3M_WOE            -0.266852   6.912786e-18\n",
    "avgPayL6M_Bin_WOE        -0.191338   5.979102e-08\n",
    "avgUrateL1M_Bin_WOE      -0.555628   1.473557e-07\n",
    "maxDelqL1M_Bin_WOE       -0.129355   1.536173e-06\n",
    "avgUrateL3M_Bin_WOE      -0.453340   1.364483e-04\n",
    "increaseUrateL3M_WOE     -0.281940   3.123852e-03\n",
    "M1FreqL12M_Bin_WOE       -0.104303   5.702452e-03\n",
    "avgUrateL6M_Bin_WOE      -0.280308   4.784200e-02\n",
    "maxUrateL3M_Bin_WOE      -0.221817   1.254597e-01\n",
    "M1FreqL6M_Bin_WOE        -0.024903   5.002232e-01\n",
    "maxUrateL6M_Bin_WOE      -0.060720   6.897626e-01\n",
    "maxPayL6M_Bin_WOE,maxUrateL6M_Bin_WOE,avgUrateL6M_Bin_WOE,avgPayL12M_Bin_WOE,increaseUrateL12M_Bin_WOE,maxPayL12M_Bin_WOE 的p值大于0.1\n",
    "单独检验显著性\n",
    "'''\n",
    " \n",
    "largePValueVars = pvalues[pvalues>0.1].index\n",
    "for var in largePValueVars:\n",
    "    X_temp = X[[var, 'intercept']]\n",
    "    logit = sm.Logit(y, X_temp)\n",
    "    logit_result = logit.fit()\n",
    "    pvalues = logit_result.pvalues\n",
    "    print(\"The p-value of {0} is {1} \".format(var, str(pvalues[var])))\n",
    "'''\n",
    "The p-value of maxPayL6M_Bin_WOE is 3.94466107162e-137 \n",
    "The p-value of maxUrateL6M_Bin_WOE is 5.83590695685e-35 \n",
    "The p-value of avgUrateL6M_Bin_WOE is 8.17633724544e-37 \n",
    "The p-value of avgPayL12M_Bin_WOE is 1.10614470149e-295 \n",
    "The p-value of increaseUrateL12M_Bin_WOE is 1.9777915301e-57 \n",
    "The p-value of maxPayL12M_Bin_WOE is 1.04348079207e-45 \n",
    "显然，单个变量的p值是显著地。说明任然存在着共线性。\n",
    "'''\n",
    "'''\n",
    "可用L1约束，直到所有变量显著\n",
    "'''\n",
    "\n",
    "\n",
    "X2 = X[featureSelected+['intercept']]\n",
    "for alpha in range(100,0,-1):\n",
    "    l1_logit = sm.Logit.fit_regularized(sm.Logit(y, X2), start_params=None, method='l1', alpha=alpha)\n",
    "    pvalues = l1_logit.pvalues\n",
    "    params = l1_logit.params\n",
    "    if max(pvalues)>=0.1 or max(params)>0:\n",
    "        break\n",
    "\n",
    "bestAlpha = alpha + 1\n",
    "l1_logit = sm.Logit.fit_regularized(sm.Logit(y, X2), start_params=None, method='l1', alpha=bestAlpha)\n",
    "params = l1_logit.params\n",
    "params2 = params.to_dict()\n",
    "featuresInModel = [k for k, v in params2.items() if k!='intercept' and v < -0.0000001]\n",
    "\n",
    "\n",
    "X_train = X[featuresInModel + ['intercept']]\n",
    "logit = sm.Logit(y, X_train)\n",
    "logit_result = logit.fit()\n",
    "trainData['pred'] = logit_result.predict(X_train)\n",
    "\n",
    "### 计算KS值\n",
    "def KS(df, score, target):\n",
    "    '''\n",
    "    :param df: 包含目标变量与预测值的数据集,dataframe\n",
    "    :param score: 得分或者概率,str\n",
    "    :param target: 目标变量,str\n",
    "    :return: KS值\n",
    "    '''\n",
    "    total = df.groupby([score])[target].count()\n",
    "    bad = df.groupby([score])[target].sum()\n",
    "    all = pd.DataFrame({'total':total, 'bad':bad})\n",
    "    all['good'] = all['total'] - all['bad']\n",
    "    all[score] = all.index\n",
    "    all = all.sort_values(by=score,ascending=False)\n",
    "    all.index = range(len(all))\n",
    "    all['badCumRate'] = all['bad'].cumsum() / all['bad'].sum()\n",
    "    all['goodCumRate'] = all['good'].cumsum() / all['good'].sum()\n",
    "    KS = all.apply(lambda x: x.badCumRate - x.goodCumRate, axis=1)\n",
    "    return max(KS)\n",
    "\n",
    "\n",
    "\n",
    "###################################\n",
    "#   5，在测试集上测试逻辑回归的结果   #\n",
    "###################################\n",
    "# 准备WOE编码后的变量\n",
    "modelFeatures = [i.replace('_Bin','').replace('_WOE','') for i in featuresInModel]\n",
    "'''\n",
    "['maxDelqL3M',\n",
    " 'increaseUrateL6M',\n",
    " 'M0FreqL3M',\n",
    " 'avgUrateL1M',\n",
    " 'M2FreqL3M',\n",
    " 'M1FreqL6M',\n",
    " 'avgUrateL3M',\n",
    " 'maxDelqL1M',\n",
    " 'avgPayL6M',\n",
    " 'M1FreqL12M']\n",
    "'''\n",
    "numFeatures = [i for i in modelFeatures if i in numericalFeatures]\n",
    "charFeatures = [i for i in modelFeatures if i in categoricalFeatures]\n",
    " \n",
    "#满足变量的数据预处理\n",
    "testData['maxDelqL1M'] = testData.apply(lambda x: DelqFeatures(x,1,'max delq'),axis=1)\n",
    "testData['maxDelqL3M'] = testData.apply(lambda x: DelqFeatures(x,3,'max delq'),axis=1)\n",
    "# testData['M2FreqL3M'] = testData.apply(lambda x: DelqFeatures(x, 3, 'M2 times'), axis=1)\n",
    "testData['M0FreqL3M'] = testData.apply(lambda x: DelqFeatures(x,3,'M0 times'),axis=1)\n",
    "testData['M1FreqL6M'] = testData.apply(lambda x: DelqFeatures(x, 6, 'M1 times'), axis=1)\n",
    "testData['M2FreqL3M'] = testData.apply(lambda x: DelqFeatures(x, 3, 'M2 times'), axis=1)\n",
    "testData['M1FreqL12M'] = testData.apply(lambda x: DelqFeatures(x, 12, 'M1 times'), axis=1)\n",
    "# testData['maxUrateL6M'] = testData.apply(lambda x: UrateFeatures(x,6,'max utilization rate'),axis = 1)\n",
    "testData['avgUrateL1M'] = testData.apply(lambda x: UrateFeatures(x,1, 'mean utilization rate'),axis=1)\n",
    "testData['avgUrateL3M'] = testData.apply(lambda x: UrateFeatures(x,3, 'mean utilization rate'),axis=1)\n",
    "# testData['avgUrateL6M'] = testData.apply(lambda x: UrateFeatures(x,6, 'mean utilization rate'),axis=1)\n",
    "testData['increaseUrateL6M'] = testData.apply(lambda x: UrateFeatures(x, 6, 'increase utilization rate'),axis=1)\n",
    "# testData['avgPayL3M'] = testData.apply(lambda x: PaymentFeatures(x, 3, 'mean payment ratio'),axis=1)\n",
    "testData['avgPayL6M'] = testData.apply(lambda x: PaymentFeatures(x, 6, 'mean payment ratio'),axis=1)\n",
    " \n",
    "#合并分箱\n",
    "testData['M2FreqL3M_Bin'] = testData['M2FreqL3M'].apply(lambda x: int(x>=1))\n",
    "testData['maxDelqL1M_Bin'] = testData['maxDelqL1M'].apply(lambda x: MergeByCondition(x,['==0','==1','>=2']))\n",
    "testData['maxDelqL3M_Bin'] = testData['maxDelqL3M'].apply(lambda x: MergeByCondition(x,['==0','==1','>=2']))\n",
    " \n",
    "for var in numFeatures:\n",
    "    newBin = var+\"_Bin\"\n",
    "    bin = [list(i.values()) for i in bin_dict if var in i][0][0]\n",
    "    testData[newBin] = testData[var].apply(lambda x: AssignBin(x,bin))\n",
    "\n",
    "finalFeatures = [i+'_Bin' for i in numFeatures] + ['M2FreqL3M_Bin','maxDelqL1M_Bin','maxDelqL3M_Bin','M0FreqL3M']\n",
    "\n",
    "for var in finalFeatures:\n",
    "    var2 = var+\"_WOE\"\n",
    "    testData[var2] = testData[var].apply(lambda x: WOE_IV_dict[var]['WOE'][x])\n",
    "\n",
    "X_test = testData[featuresInModel]\n",
    "X_test['intercept'] = [1]*X_test.shape[0]\n",
    "testData['pred'] = logit_result.predict(X_test)\n",
    "\n",
    "\n",
    "ks = KS(testData, 'pred', 'label')\n",
    "auc = roc_auc_score(testData['label'],testData['pred'])\n",
    "# KS＝64.94%， AUC ＝ 84.43%，都高于30%的标准。因此该模型是可用的。\n",
    "\n",
    "##########################\n",
    "#   6，在测试集上计算分数   #\n",
    "##########################\n",
    "def Prob2Score(prob, basePoint, PDO):\n",
    "    #将概率转化成分数且为正整数\n",
    "    y = np.log(prob/(1-prob))\n",
    "    return int(basePoint+PDO/np.log(2)*(-y))\n",
    " \n",
    "BasePoint, PDO = 500,50\n",
    "testData['score'] = testData['pred'].apply(lambda x: Prob2Score(x, BasePoint, PDO))\n",
    "plt.hist(testData['score'],bins=100)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
